package org.example.util.parser;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import org.example.vo.DocxVo;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;

@Slf4j
public class DocxParser implements ParserInter {

    @Override
    public DocxVo parse(MultipartFile file) {
        DocxVo vo = new DocxVo();

        try (InputStream in = file.getInputStream();
             XWPFDocument document = new XWPFDocument(OPCPackage.open(in))) {

            List<XWPFParagraph> paragraphs = document.getParagraphs();
            if (paragraphs.isEmpty()) {
                vo.setTitle("未命名文档");
                vo.setContent("");
                return vo;
            }

            // 1️提取标题（优先查找标题样式或较大字号）
            String title = extractTitle(paragraphs);
            vo.setTitle(title);

            // 2️提取正文（拼接所有段落文本）
            StringBuilder contentBuilder = new StringBuilder();
            for (XWPFParagraph p : paragraphs) {
                String text = p.getText();
                if (StringUtils.isBlank(text)) continue;

                // 跳过目录、TOC 等系统段落
                if (isFieldCode(text) || isTocParagraph(text) || text.equals(title)) continue;

                contentBuilder.append(cleanText(text)).append("\n");
            }

            vo.setContent(contentBuilder.toString().trim());
        } catch (Exception e) {
            log.error(" Apache POI 解析 DOCX 失败: {}", e.getMessage());
            vo.setTitle("无法读取文档");
            vo.setContent("");
        }

        return vo;
    }

    /**
     * --------------------------- 提取标题 ---------------------------
     */
    private String extractTitle(List<XWPFParagraph> paragraphs) {
        for (int i = 0; i < Math.min(paragraphs.size(), 10); i++) {
            XWPFParagraph p = paragraphs.get(i);
            String text = p.getText();
            if (StringUtils.isBlank(text)) continue;

            // 检查是否样式名为标题
            String style = p.getStyle();
            if (style != null && style.toLowerCase().contains("title")) {
                return text.trim();
            }

            // 检查字号是否较大
            if (hasLargeFont(p)) {
                return text.trim();
            }

            // 作为后备策略，首个非空文本也作为标题
            if (i == 0) {
                return text.trim();
            }
        }
        return "未命名文档";
    }

    private boolean hasLargeFont(XWPFParagraph p) {
        for (XWPFRun run : p.getRuns()) {
            if (run.getFontSize() > 16) {
                return true;
            }
        }
        return false;
    }

    /**
     * --------------------------- 内容过滤 ---------------------------
     */
    private boolean isFieldCode(String text) {
        if (StringUtils.isBlank(text)) return false;
        String t = text.trim();
        return t.startsWith("TOC") ||
                t.startsWith("HYPERLINK") ||
                t.startsWith("PAGEREF") ||
                t.startsWith("_Toc") ||
                t.matches(".*\\\\o.*") ||
                t.matches(".*\\\\h.*") ||
                t.matches(".*\\\\u.*");
    }

    private boolean isTocParagraph(String text) {
        String t = text.trim();
        return t.contains("目录") || t.startsWith("TOC") || t.matches(".*_Toc\\d+.*");
    }

    /**
     * --------------------------- 内容清理 ---------------------------
     */
    private String cleanText(String text) {
        if (StringUtils.isBlank(text)) return "";
        return text
                .replaceAll("_Toc\\d+", "")
                .replaceAll("HYPERLINK\\s+\"[^\"]*\"", "")
                .replaceAll("PAGEREF\\s+[^\\s]+\\s+\\\\h", "")
                .replaceAll("\\\\[a-zA-Z]+", "")
                .replaceAll("\\s{2,}", " ")
                .trim();
    }
}
